from datetime import datetime, timedelta
from django import forms
from django.template import Context, loader
from django.http import HttpResponse, Http404, HttpResponseRedirect
from monulu.raid.models import Raid, Character, Boss, Item, Instance, Raider
from monulu.sk.models import SKList, SKSuicide

class RaidResult(object):
    def __init__(self, raid):
        self.raid = raid
        self.ranks = []
        self.suicides = []

    def __cmp__(self, other):
        if isinstance(other, int):
            return cmp(self.raid.pk, other)
        if isinstance(other, unicode):
            return cmp (self.raid.pk, int(other))
        return cmp(self.raid.pk, other.raid.pk)
    def getId(self):
        return self.raid.pk

class RaidRank(object):
    def __init__(self, key, char, rank, inraid, suicides):
        self.key = key
        self.char = char
        self.rank = rank
        self.inraid = inraid
        self.suicides = suicides
    def __cmp__(self, other):
        return cmp(self.rank, other.rank)
    
def index(request):
    lists = []
    sklists = SKList.objects.all().order_by('pk')
    for l in sklists:
        listRanks = []
        raid = l.getLastRaid()
        for rank in l.getRanks():
            char = Character.objects.get(pk=rank[0])
            listRanks.extend([RaidRank(rank[0], 
                             char,
                             rank[1], 
                             raid.isInRaid(char),
                             SKSuicide.objects.filter(raid=raid, character=char))])
        lists.append(listRanks)
        
    t = loader.get_template('sk/index.html')
    c = Context({'sklists': sklists,'ranklist':lists})
    return HttpResponse(t.render(c))

def history(request, list_id, raid_id=0):
    skl = SKList.objects.get(pk=list_id)
    if not raid_id:
        raid_id = skl.getLastRaid().pk
    hraids = [RaidResult(raid) for raid in skl.getRaids()]
    if not raid_id in hraids:
        raise Http404
    # slicing raids at the specified point    
    i = hraids.index(raid_id)
    hraids = hraids[:i+1]
    
    for hraid in hraids:
        hraid.ranks = skl.getRanks(hraid.getId())
        hraid.suicides = SKSuicide.objects.filter(raid=hraid.getId()).order_by('skorder')

    # The ranks arrays will always be the same length as they are each 
    # derived from SKStart
    rt=[[] for h in hraids[0].ranks]

    for i in range (0, len(hraids[0].ranks)):
        for hraid in hraids:
            char = Character.objects.get(pk=hraid.ranks[i][0])
            rt[i].extend([RaidRank(hraid.ranks[i][0], 
                          char,
                          hraid.ranks[i][1], 
                          hraid.raid.isInRaid(char),
                          SKSuicide.objects.filter(raid=hraid.raid,character=char))])

    t = loader.get_template('sk/history.html')
    c = Context({'hraids':hraids,'rt': rt,})
    return HttpResponse(t.render(c))


class NewRaidForm(forms.Form):
    instance = forms.ChoiceField(label=u'Instance')
    size = forms.IntegerField(label=u'Size', initial=12)
    start = forms.DateTimeField(label=u'Start time')
    end = forms.CharField(label=u'Ends', required=False, initial='-')
    def __init__(self, request=None, **kwargs):
        self.request = request
        if request and self.request.method == 'POST':
            kwargs['data'] = self.request.POST
        super(NewRaidForm, self).__init__(**kwargs)
        self.fields['instance'].choices = [(i.id,i) for i in Instance.objects.all()]
        self.fields['start'].initial=datetime.now()
    

def admin(request):
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/login/?next=%s' % request.path)
    if request.method == 'POST':
        newRaidForm = NewRaidForm(request)
        if newRaidForm.is_valid():
            raid = Raid()
            raid.characters_required = newRaidForm.cleaned_data['size']
            raid.instance = Instance.objects.get(pk=newRaidForm.cleaned_data['instance'])
            raid.start_time = newRaidForm.cleaned_data['start']
            raid.end = newRaidForm.cleaned_data['end']
            raid.save()
    else:
        newRaidForm = NewRaidForm()
        
    yesterday = datetime.today() - timedelta(5) # list raids up to x days old 
    raids = Raid.objects.filter(start_time__gte=yesterday).order_by('-start_time')
    t = loader.get_template('sk/admin.html')
    c = Context({'raids':raids, 'newRaidForm':newRaidForm})
    return HttpResponse(t.render(c))

class RaidAdminForm(forms.Form):
    bossid = forms.ChoiceField(label=u'Boss')
    lootitems = forms.ChoiceField(label=u'Loot')
    
    def __init__(self, raid, request=None, **kwargs):
        self.request = request
        if request and self.request.method == "POST":
            kwargs['data'] = self.request.POST
        else:
            kwargs['data'] = {}
        bosses = Boss.objects.filter(instance=raid.instance)
        bid = kwargs['data'].get('bossid')
        if not bid:
            boss = bosses[0]
        else:
            boss = Boss.objects.get(pk=bid)

        loots = Item.objects.filter(boss=boss)
        lootchoices = [(i.id,i.__unicode__()) for i in loots]
        super(RaidAdminForm, self).__init__(**kwargs)
        choices = [(r.id,r.__unicode__()) for r in bosses]
        self.fields['bossid'].choices = choices
        self.fields['lootitems'].choices = lootchoices
        

def adminraid(request, raid_id):
    raid = Raid.objects.get(pk=raid_id)
    if not request.user.is_authenticated():
        return HttpResponseRedirect('/login/?next=%s' % request.path)
    if request.method == 'POST':
        raidform = RaidAdminForm(raid, request)
        if raidform.is_valid():
            boss = raidform.cleaned_data['bossid']
        else:
            bossid = 0
    else:
        raidform = RaidAdminForm(raid)
        bossid = 0
    yesterday = datetime.today() - timedelta(5) # list raids up to x days old 
    raids = Raid.objects.filter(start_time__gte=yesterday).order_by('-start_time')
    raiders = Raider.objects.filter(raid=raid)
    t = loader.get_template('sk/adminraid.html')
    c = Context({'raidform':raidform,'raids':raids, 'raid':raid, 'raiders':raiders })
    return HttpResponse(t.render(c))

